package com.bluesea.common;

import java.util.ArrayList;
import java.util.List;



public class Page<T> {

	private int pageSize = Constants.DEFAULT_PAGE_SIZE; 
	private int pageNumber;
	private List<T> results; 
	private int recordCount; 
	private int indexNumber = Constants.DEFAULT_INDEX_NUMBER;

	public Page() {
		this(Constants.DEFAULT_PAGE_SIZE, 0, new ArrayList<T>(),
				Constants.DEFAULT_INDEX_NUMBER, 1);
	}

	/**
	 * 
	 * @param pageSize
	 * @param recordCount
	 * @param results
	 * @param pageNumber
	 */
	public Page(int pageSize, int recordCount, List<T> results, int pageNumber) {
		this(pageSize, recordCount, results, Constants.DEFAULT_INDEX_NUMBER,
				pageNumber);
	}

	/**
	 * @param pageSize
	 * @param recordCount
	 * @param results
	 * @param indexNumber
	 * @param pageNumber
	 */
	public Page(int pageSize, int recordCount, List<T> results,
			int indexNumber, int pageNumber) {
		super();
		this.pageSize = pageSize < 1 ? 1 : pageSize;
		this.results = results;
		this.recordCount = recordCount < 0 ? 0 : recordCount;
		this.indexNumber = indexNumber < 0 ? 0 : indexNumber;
		this.pageNumber = pageNumber < 1 ? 1
				: pageNumber > getPageCount() ? getPageCount() : pageNumber;
	}

	/**
	 * @return the pageSize
	 */
	public int getPageSize() {
		return pageSize;
	}

	/**
	 * @param pageSize
	 *            the pageSize to set
	 */
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize < 1 ? 1 : pageSize;
	}

	/**
	 * @return the pageNumber
	 */
	public int getPageNumber() {
		return pageNumber;
	}

	/**
	 * @param pageNumber
	 *            the pageNumber to set
	 */
	public void setPageNumber(int pageNumber) {
		this.pageNumber = pageNumber < 1 ? 1
				: pageNumber > getPageCount() ? getPageCount() : pageNumber;
	}

	/**
	 * @return the results
	 */
	public List<T> getResults() {
		return results;
	}

	/**
	 * @param results
	 *            the results to set
	 */
	public void setResults(List<T> results) {
		this.results = results;
	}

	/**
	 * @return the recordCount
	 */
	public int getRecordCount() {
		return recordCount;
	}

	/**
	 * @param recordCount
	 *            the recordCount to set
	 */
	public void setRecordCount(int recordCount) {
		this.recordCount = recordCount < 0 ? 0 : recordCount;
	}

	/**
	 * @return the pageIndex
	 */
	public int[] getPageIndex() {
		int start = pageNumber
				- (indexNumber % 2 == 0 ? indexNumber / 2 - 1 : indexNumber / 2);
		int end = pageNumber + indexNumber / 2;
		if (start < 1) {
			start = 1;
			if (getPageCount() >= indexNumber) {
				end = indexNumber;
			} else {
				end = getPageCount();
			}
		}
		if (end > getPageCount()) {
			end = getPageCount();
			if ((end - indexNumber) > 0) {
				start = end - indexNumber + 1;
			} else {
				start = 1;
			}
		}

		int[] pageIndex = new int[end - start + 1];
		for (int i = start; i <= end; i++) {
			pageIndex[i - start] = i;
		}

		return pageIndex;
	}

	/**
	 * @return the indexNumber
	 */
	public int getIndexNumber() {
		return indexNumber;
	}

	/**
	 * @param indexNumber
	 *            the indexNumber to set
	 */
	public void setIndexNumber(int indexNumber) {
		this.indexNumber = indexNumber;
	}

	public boolean hasPreviousPage() {
		return pageNumber > 1;
	}

	public boolean hasNextPage() {
		return pageNumber < getPageCount();
	}

	/**
	 * @return the pageCount
	 */
	public int getPageCount() {
		if (recordCount == 0)
			return 1;
		if (recordCount % pageSize == 0) {
			return recordCount / pageSize;
		} else {
			return recordCount / pageSize + 1;
		}
	}

	public static int getStartRow(int pageNumber, int pageSize) {
		return (pageNumber <= 1 ? 0 : (pageNumber - 1))
				* (pageSize < 1 ? 1 : pageSize);
	}

}
